package com.smartleanx.module.hrm.app.empRisk;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.smartleanx.framework.common.enums.CommonStatusEnum;
import com.smartleanx.framework.common.util.collection.CollectionUtils;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeContractDO;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeDO;
import com.smartleanx.module.hrm.dal.dataobject.programme.HrmProgrammeEmployee;
import com.smartleanx.module.hrm.dal.dataobject.risk.RiskTypeDO;
import com.smartleanx.module.hrm.enums.ErrorCodeConstants;
import com.smartleanx.module.hrm.eums.employee.EmployeeStatusEnum;
import com.smartleanx.module.hrm.eums.employee.EmploymentFormEnum;
import com.smartleanx.module.hrm.eums.risk.RiskLevelEnum;
import com.smartleanx.module.hrm.eums.risk.RiskTypeEnum;
import com.smartleanx.module.hrm.service.employee.EmployeeContractService;
import com.smartleanx.module.hrm.service.employee.EmployeeService;
import com.smartleanx.module.hrm.service.programme.HrmProgrammeEmployeeService;
import com.smartleanx.module.hrm.service.risk.RiskService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.smartleanx.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 是否缴纳社保
 *
 * @author tengcj
 * @since 2024/6/11
 */
@Component
public class RiskSocialSecurityHandleService implements EmployeeRiskHandle {

    @Resource
    private EmployeeService employeeService;

    @Resource
    private EmployeeContractService employeeContractService;
    @Resource
    private HrmProgrammeEmployeeService hrmProgrammeEmployeeService;

    @Resource
    private RiskService riskService;

    public static final long RISK_ID = RiskTypeEnum.SOCIAL_SECURITY_PAYMENT.getCode();

    @Override
    public Long type() {
        return RISK_ID;
    }

    @Override
    public void handleEmployeeRisk(Set<Long> employeeIds) {
        List<EmployeeDO> employeeList = employeeService.getEmployeeList(employeeIds);
        if (CollUtil.isEmpty(employeeList)) {
            riskService.deleteRisk(employeeIds, RISK_ID);
            return;
        }
        RiskTypeDO riskType = riskService.getRiskType(RISK_ID);
        if (riskType == null) {
            throw exception(ErrorCodeConstants.RISK_TYPE_NOT_EXISTS);
        }

        //1. 查询员工缴纳社保
        List<HrmProgrammeEmployee> programmeEmpList = hrmProgrammeEmployeeService.getProgrammeEmpList(employeeIds);
        Map<Long, List<HrmProgrammeEmployee>> map = programmeEmpList.stream().collect(Collectors.groupingBy(HrmProgrammeEmployee::getUserId));
        //2. 循环员工列表
        for (EmployeeDO employeeDO : employeeList) {
            //2.1 员工离职  没有改风险点
            if(employeeDO.getState() == EmployeeStatusEnum.SEPARATED.getCode()){
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
                continue;
            }
            //2.2 员工非正式  没有风险点
            if (Objects.equals(EmploymentFormEnum.INFORMAL.getCode(), employeeDO.getEmploymentForm())) {
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
                continue;
            }
            //2.3 在职 正式员工
            List<HrmProgrammeEmployee> list = map.get(employeeDO.getId());
            //2.4 没有缴纳记录  产生风险点
            if(CollUtil.isEmpty(list)){
                riskService.addRiskToEmployee(employeeDO.getId(), RISK_ID, RiskLevelEnum.MAJOR.getLevel());
                continue;
            }
            //2.5 有缴纳记录  已经停缴  产生风险点
            HrmProgrammeEmployee beforeProgrammeEmp = null;//当前时间的 前一条记录
            HrmProgrammeEmployee currentProgrammeEmp = null;//当前时间的 当前记录
            for (HrmProgrammeEmployee programmeEmployee : list) {
                //2.5.1 社保缴纳时间为空  跳过
                if(programmeEmployee.getProgrammeStartTime().isEmpty()){
                    continue;
                }

                DateTime empStartTime = DateUtil.parse(programmeEmployee.getProgrammeStartTime(), DatePattern.NORM_MONTH_PATTERN);
                DateTime currentTime = DateUtil.parse(DateUtil.format(DateUtil.date(),DatePattern.NORM_MONTH_PATTERN), DatePattern.NORM_MONTH_PATTERN);

                //员工缴纳时间 小于 当前时间   是整数  反之负数    -8888
                long between = DateUtil.between(empStartTime, currentTime, DateUnit.SECOND, false);
                //2.5.2 缴纳时间等于当前时间
                if(between == 0){
                    if(null == currentProgrammeEmp || programmeEmployee.getProgrammeState() == 1){
                        currentProgrammeEmp = programmeEmployee;
                    }
                    continue;
                }
                if(currentProgrammeEmp != null){
                    continue;
                }
                //2.5.3 缴纳时间小于当前时间  并且前一个记录为空
                if(between > 0){
                    if(null == beforeProgrammeEmp ||
                            between < DateUtil.between(DateUtil.parse(beforeProgrammeEmp.getProgrammeStartTime(), DatePattern.NORM_MONTH_PATTERN), currentTime, DateUnit.SECOND, false)){
                        beforeProgrammeEmp = programmeEmployee;
                    }
                }
            }
            /*  -----   获取最近一条缴纳记录结束   --------*/
            //2.6 当前缴纳记录 不为空  判断是否正常缴纳
            beforeProgrammeEmp = null != currentProgrammeEmp?currentProgrammeEmp:beforeProgrammeEmp;

            if(null == beforeProgrammeEmp || beforeProgrammeEmp.getIsProgramme() == 0 || beforeProgrammeEmp.getProgrammeState() == 2){
                riskService.addRiskToEmployee(employeeDO.getId(), RISK_ID, RiskLevelEnum.MAJOR.getLevel());
            }else{
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
            }

        }


//        Map<Long, List<EmployeeContractDO>> contractMap = CollectionUtils.convertMultiMap(
//                employeeContractService.getInProgressContractList(employeeIds), EmployeeContractDO::getEmployeeId
//        );
//
//        for (EmployeeDO employeeDO : employeeList) {
//            if (Objects.equals(EmploymentFormEnum.INFORMAL.getCode(), employeeDO.getEmploymentForm())) {
//                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
//                continue;
//            }
//            List<EmployeeContractDO> contractList = contractMap.get(employeeDO.getId());
//            if (CollUtil.isEmpty(contractList)) {
//                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
//                return;
//            }
//            EmployeeContractDO contract = CollectionUtils.findFirst(contractList, Objects::nonNull);
//            if (contract == null) {
//                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
//                return;
//            }
//            if (CommonStatusEnum.DISABLE.getStatus().equals(contract.getIsSocialSecurity())) {
//                riskService.addRiskToEmployee(employeeDO.getId(), RISK_ID, RiskLevelEnum.MAJOR.getLevel());
//                continue;
//            }
//            riskService.deleteRisk(employeeDO.getId(), RISK_ID);
//        }

    }

}
